/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023.
 * Description: rtos gicv3 enhance feature functions
 * Author: huyizhou
 * Create: 2023-09-14
 */

#ifdef CONFIG_RTOS_HAL_IRQ_BYPASS
static inline struct irq_desc *get_fast_irq_desc(u32 irqnr)
{
	if (unlikely(irqnr <= HI1382_HERT_IPI_MIN ||
		     (irqnr >= HI1382_SPI_HWIRQ_MAX && irqnr < HI1382_LPI_MIN)))
		return NULL;
	/*
	 * MSI_IRQ_BASE is defined under CONFIG_RTOS_HAL_LINEAR_MAP, it represents the
	 * first effective value of msi irq
	 */
	if (irqnr >= HI1382_LPI_MIN && irqnr < HI1382_VIRQ_NUMS + HI1382_LPI_SPI_DIFF) {
		irqnr = mbigen_irq[irqnr - HI1382_LPI_SPI_DIFF].virq;
		if (unlikely(!irqnr))
			return NULL;
	}

	return irq_to_desc(irqnr);
}
#endif

#ifdef CONFIG_RTOS_HAL_SET_IRQPRIORITY
static int gic_set_pri(struct irq_data *d, u8 prio)
{
	void __iomem *reg = NULL;

	if (!d) {
		pr_err("[%s]%d irq data is NULL!\n", __func__, __LINE__);
		return -EINVAL;
	}

	if (prio < MIN_IRQ_PRI_NUM || prio >= DEFAULT_PMR_VALUE) {
		pr_err("[%s]%d prio %u out of restriction\n",
					__func__, __LINE__, prio);
		return -EINVAL;
	}

	if (d->irq < MIN_IRQ_NUM) {
		pr_err("[%s]%d irq num %d out of restriction\n",
					__func__, __LINE__, d->irq);
		return -EINVAL;
	}

	reg = gic_dist_base(d) + GICR_IPRIORITYR0 + gic_irq(d);
	writeb_relaxed(prio, reg);

	return 0;
}

static int gic_get_pri(struct irq_data *d, u8 *prio)
{
	void __iomem *reg = NULL;

	if (!prio)
		return -EINVAL;

	if (!d) {
		pr_err("[%s]%d irq data is NULL!\n", __func__, __LINE__);
		return -EINVAL;
	}

	if (d->irq < MIN_IRQ_NUM) {
		pr_err("[%s]%d irq num %d out of restriction\n",
					__func__, __LINE__, d->irq);
		return -EINVAL;
	}

	reg = gic_dist_base(d) + GICR_IPRIORITYR0 + gic_irq(d);
	*prio = readb_relaxed(reg);

	return 0;
}
#endif
